import { Sendcontroller } from './lib/sendController'
import { ReceiverController } from './lib/receiverController'
import { start, stop } from "./lib/timing";
import TalkObject from './lib/talkObject';
const talkObject = new TalkObject();
// let closeReason = "true";                                       //记录断开连接的原因

let config = sessionStorage.getItem("config");                     //用户config 
config = config ? JSON.parse(config) : '';
const _getSo = Symbol("_getSo"),
    _getHttp = Symbol('_getHttp'),
    _login = Symbol('_login'),
    _sendServerMsg = Symbol('_sendServerMsg'),
    _setTime = Symbol('_setTime');
export class Socket {
    static instance = null;     // 实例
    #loginData = {
        // h_url: '',
        // a_url: '',
        // e_url: '',
        // port: '',               // pc or mobile
        // sertype: '',            // 用户系统
        // username: '',           // 用户账号     
        // password: '',           // 用户密码
        // token: "",              // 用户token
        // onLoginSuccess: null,   // 通知改变数据 
        // onCloseCallback :null , //
        userData: { member_id: 0 },
        userLoginStatus: {         //用户登录状态数据
            leaveType: 0,          //0.初始化  1 .被踢下线   2. socket断开 
            isOnLine: false,       //true在线 ,   false 离线
            userSelect: 0,         //0.没有选择 ，1.继续连接  2.不连接
            timeOff: ''            //定时器开关
        }
    }
    constructor() {
        if (!Socket.instance) {
            Socket.instance = this;
            Socket.instance.so = null;
            config ? this.#loginData = { ...this.#loginData, ...config } : '';
            let userData = sessionStorage.getItem('userData');
            if (userData) {
                userData = JSON.parse(userData);
                const { username, password } = userData;
                if (username && password) { Socket.instance[_login](username, password); }
            }
            console.log("创建socket实例。", this.#loginData)
        }
        return Socket.instance;
    }
    /*设置用户名和密码*/
    setUserNameAndPassword(username, password) {
        this.#loginData.username = username;
        this.#loginData.password = password;
        console.log(username, password)
        if (username != '' && password != '') { this[_login](username, password); }
    }
    /*发送会话消息*/
    sendTalkMsg(talk_id, content, type) {
        if (!talk_id || !content || !type) { return /*alert("缺少参数！")*/ }
        const ret = this.sendcontroller.pushMessage("talk", { content: content, talk_id: talk_id, type: type }, this.#loginData.userData.member_id);
        if (ret.code != 200) { return ret }
        this.sendcontroller.sendMessage(ret.data.data.head.clientMsgId)
    }
    /*创建临时会话*/
    makeDialogue(title, toMemberId, content, succCallback, failCallback) {
        if (!title || !toMemberId || !succCallback || !failCallback) {
            confirm("参数缺失！");
            return
        }
        if (toMemberId == this.#loginData.userData.member_id) {
            alert("toMemberId 和 用户MemberId 相同！");
            return
        }
        var token = this.#loginData.userData.token;
        this[_getHttp](this.#loginData["h_url"] + "/makeTemporaryTalk", { title, token, toMemberId },
            data => {
                if (data.code == 200) {
                    // 1.创建一条会话消息
                    this[_sendServerMsg]("makeTemporaryTalk", { dialogueKey: data.data.dialogueKey }, toMemberId, succCallback, failCallback);
                    Sendcontroller.makeTemporaryTalkContent = content;
                    console.log("content", content)
                } else {
                    return alert("请求错误！" + data.data);
                }
            }
        );
    }
    /*取会话列表*/
    getTalkList() {
        return talkObject.getTalkList();
    }
    /*历史记录*/
    getChat(talk_id) {
        if (!talk_id) {
            talk_id = prompt("请输入talk_id")
        }
        return talkObject.getChat(talk_id);
    }
    /*取会话详情*/
    getTalkDetail(talk_id) {
        if (!talk_id) {
            talk_id = window.prompt("输入talk_id");
        }
        return talkObject.getTalkDetail(talk_id);
    }
    /*取会话用户信息*/
    getTalkDetail01(talk_id) {
        return talkObject.getTalkDetail01(talk_id);
    }
    /*talkObject添加回调函数*/
    addTalkObjectCallback(onNewChatAlert, onListRefresh, onTalkDetailRefresh, onTalkWithMsg) {
        // for (let i of arguments) {
        //     if (typeof i != "function") {
        //         confirm("参数必须为函数！")
        //         return
        //     }
        // }
        talkObject.addCallBack(onNewChatAlert, onListRefresh, onTalkDetailRefresh, onTalkWithMsg)
    }
    /*消息重发*/
    resend(clientMsgId) {
        if (!clientMsgId) {
            return alert("resend 参数错误！")
        }
        var data = talkObject.findMessage(clientMsgId);
        if (data.code == 200) {
            this.sendcontroller.sendMessage(data.data.head.clientMsgId)
        }
    }
    /*本地存储清空*/
    clearStorage() {
        sessionStorage.clear();
        localStorage.clear();
    }
    /*socket实例*/
    setConfig(option) {
        const required = ['h_url', 'a_url', 'e_url', 'port', 'sertype', 'onLoginSuccess', 'onCloseCallback'];        //必填字段
        const falg = required.find(key => {                                     //必填字段验证
            if (!option[key] && key) { return key }
        })
        if (typeof option.onLoginSuccess != "function") {
            alert("onLoginSuccess 必需为函数！");
            return
        }
        if (falg) { alert(falg + "字段缺失!"); return {} }
        this.#loginData = { ...this.#loginData, ...option };                        //赋值
        config = option;
        talkObject.initSessionStorage(this.#loginData);                             //本地存储 config
        if (option.username && option.password) {
            this[_login](option.username, option.password);                         //登录
        }
    }
    /*（测试）打印用户信息*/
    showUserData() {
        return this.#loginData.userData;
    }
    /*（测试）打印用户信息*/
    getTalkObject() {
        return talkObject
    }
    /*更改用户头像*/
    editAvatarurl(file) {
        let url = this.#loginData.a_url + '/editAvatarurl?key=' + this.#loginData.key;
        const formdata = new FormData();
        formdata.append('file', file);
        var xmlpost = new XMLHttpRequest();
        xmlpost.open("post", url, true);
        xmlpost.send(formdata);
        xmlpost.onreadystatechange = function () {
            if (xmlpost.readyState == 4) {
                if (xmlpost.status == 200) {
                    var data = JSON.parse(xmlpost.responseText);
                    if (data.code != 200) {
                        console.log("请求出错", data.data);
                    }
                    console.log(data.data);
                }
            }
        }
    }
    /*更改用户姓名*/
    editSelfName(name) {
        if (!name) {
            alert("用户名为空!")
            return
        }
        let url = this.#loginData.a_url + '/editSelfName';
        this[_getHttp](url, { name, key: this.#loginData.key }, (data) => {
            if (data.code != 200) {
                console.log(data.data);
                return
            }
            console.log(data.data);
            this[_sendServerMsg]('refreshInEditSelfInfo', {}, this.#loginData.userData.member_id);  //修改成功时，发送一条消息确认
        })
    }
    /*用户退出聊天界面*/
    exit() {
        talkObject.exit();
    }
    /*用户快速连接*/
    quickConnect(key, token) {
        console.log(key, token)
    }
    /*登录*/
    [_login](username, password) {
        if (!username || !password) {
            alert("账号密码不能为空！")
            return
        }
        if (!config || !config.a_url) {
            console.log("config为空！")
            return
        }
        if (this.so && this.so.readyState == 1) {
            // 不要重复登录！
            // alert("_login,011")
            return
        }
        var that = this;
        const post = { username, password, sertype: that.#loginData.sertype };
        getToken(username, password, function (key, token) {
            that[_getHttp](
                that.#loginData['h_url'] + "/getLoginKey",
                { token: token, port: that.#loginData.port },
                function (data) {
                    if (data.code == 200) {
                        var loginKey = data.data.loginKey;
                        var isForceLogin = data.data.isNeedForceLogin;
                        let url = "ws://" + that.#loginData['e_url'] + ":2345"; //url='ws://e.com:2345';
                        that[_getSo](
                            url,
                            key,
                            loginKey,
                            token,
                            isForceLogin,
                            that.#loginData.sertype,  //用户系统
                            /* 成功回调*/
                            function (res) {
                                console.log("so 连接成功！")
                                start();                                             //开始心跳连接
                                that.#loginData.userLoginStatus.isOnLine = true;
                                that[_setTime]();                                    //检测 用户连接状态
                                that.#loginData.userData = res.data.userData;
                                that.#loginData.userData.username = username;
                                that.#loginData.userData.password = password;
                                that.#loginData.userData.token = token;
                                that.receiverController.setMemberId(res.data.userData.member_id);
                                that.#loginData.onLoginSuccess ? that.#loginData.onLoginSuccess({
                                    userData: res.data.userData,
                                    token,
                                }) : '';
                                var userData = JSON.stringify(res.data.userData);
                                sessionStorage.setItem("userData", userData);
                                var list = talkObject.fetchLocalStorage(res.data.userData.member_id, res.data.userData.sertype, res.data.userData.port);
                                if (list.code != 200) {
                                    return
                                }
                                talkObject.talkList = list.data;
                            },
                            /* 失败回调*/
                            function () {
                                // res
                                // console.log("登录失败！", res);
                            }
                        );
                    }
                }
            );
        });
        function getToken(username, password, onOk) {
            that[_getHttp](that.#loginData['a_url'] + "/cPasswordGetKey", post, function (data) {
                if (data.code == 200) {
                    var key = data.data.key;
                    that.#loginData.key = key;
                    that[_getHttp](that.#loginData['h_url'] + "/login", { key: key }, function (data) {
                        if (data.code == 200) {
                            var token = data.data.token;
                            that.#loginData.token = token;
                            onOk(key, token);
                        } else {
                            alert('程序错误，h项目登录失败');
                        }
                    })
                } else {
                    console.log("断开！密码错误！重新输入密码！")
                    that.setUserNameAndPassword('', '');                //账号或密码不正确时，清空账号密码
                }
            })
        }
    }
    /*判断登录状态*/
    readyStateLogin(onSuccess) {
        let i = setInterval(() => {
            if (this.#loginData.userLoginStatus.isOnLine) {
                clearInterval(i);
                onSuccess();
            }
        }, 1000);
    }
    /*socket连接 ，so监听事件*/
    [_getSo](url, key, loginKey, token, isForceLogin, sertype, callback, failCallback) {
        for (let i in arguments) {
            if (arguments[i] == undefined || arguments[i] == '') {
                console.log("getSo,第" + i + "个参数不能为空！");
                return
            }
        }
        const that = this;
        if (this.so == null) {
            this.so = new WebSocket(url);
            this.so.onerror = () => { console.log("so连接失败！") };
            that.so.onopen = function () {
                if (that.so.readyState == 1) {
                    that.sendcontroller = new Sendcontroller(that.so);              //socket 成功连接时，实例化发送器实例
                    that.receiverController = new ReceiverController(that.so);     //接收器
                    that[_sendServerMsg]("login", {
                        key: key,
                        loginKey: loginKey,
                        token: token,
                        sertype: sertype,
                        isForceLogin: isForceLogin,
                    });
                }
            };
            /*数据接收监听，接收服务器推送过来的信息，返回的数据给msg，然后进行显示*/
            this.so.onmessage = function (msg) {
                var data = JSON.parse(msg.data);
                if (data.head.ms == 1) {                                            //服务端发送的数据
                    that.receiverController.receiverMsg(data);
                    if (data.head.action == "login") {
                        that.#loginData.userLoginStatus.isOnLine = false;
                        that.#loginData.userLoginStatus.userSelect = 0;
                        that.#loginData.userLoginStatus.leaveType = 1;
                        const res = that.#loginData.onCloseCallback();
                        console.log(res)
                        if (res) {
                            that.#loginData.userLoginStatus.userSelect = 1
                        } else {
                            that.#loginData.userLoginStatus.userSelect = 2;
                            that.#loginData.onLoginSuccess({ userData: { member_id: 0 } });
                            sessionStorage.clear();
                            that.so = null;
                            clearInterval(that.#loginData.userLoginStatus.timeOff);
                            console.log("不连了！");
                            console.log(that.#loginData.userLoginStatus)
                        }
                    }
                } else {                                                            //服务端回执的数据, 回执
                    that.sendcontroller.getServerReceiptMsg(data);
                }
                if (data.head.action == 'login') {
                    if (data.body.code == 200) { callback(data.body) } else { failCallback && failCallback(data.body); }
                }
            };
            this.so.onclose = function () {
                if (that.#loginData.userLoginStatus.leaveType != 1) {
                    that.#loginData.userLoginStatus.leaveType = 2;
                }
                that.#loginData.userLoginStatus.isOnLine = false;
                that.so = null;
                that.#loginData.onLoginSuccess({ userData: { member_id: 0 } });     //更新视图层
                stop();                                                             //停止心跳检测
                console.log("断开连接！");
                console.log(that.so);
            };
        }
    }
    /*请求*/
    [_getHttp](url, params, callback) {
        for (let i in arguments) {
            if (arguments[i] == undefined || arguments[i] == '') {
                alert("getHttp参数，第 " + i + "个参数不能为空！");
                return
            }
        }
        var xmlpost = new XMLHttpRequest();
        xmlpost.open("post", url, true);
        var postData = [];
        if (params) {
            for (let i in params) {
                postData.push(i + "=" + params[i]);
            }
            postData = postData.join("&");
        }
        xmlpost.send(postData);
        xmlpost.onreadystatechange = function () {
            if (xmlpost.readyState == 4) {
                if (xmlpost.status == 200) {
                    var data = JSON.parse(xmlpost.responseText);
                    callback(data);
                    if (data.code != 200) {
                        console.log("请求出错", data.data);
                    }
                }
            }
        };
    }
    /*打印用户信息*/
    [_sendServerMsg](sign, content, toMemberId, succCallback, failCallback) {
        for (let i in arguments) {
            if (arguments[i] == '' || arguments[i] == undefined) {
                alert("sendServerMsg，第" + i + "个参数不能为空！");
                return
            }
        }
        const msg = this.sendcontroller.pushMessage(sign, content, toMemberId, succCallback, failCallback);
        if (msg.code != 200) { alert("消息创建失败！"); return }
        console.log(msg)
        // if(sign=="makeTemporaryTalk"){
        //    const talkMsg = this.sendcontroller.pushMessage('talk', { content: content.content, talk_id: '', type: 2 }, this.#loginData.userData.member_id);
        //     console.log(talkMsg);
        // }
        this.sendcontroller.sendMessage(msg.data.data.head.clientMsgId);
    }
    /*定时检测so是否断开连接*/
    [_setTime]() {
        const controller = this.#loginData.userLoginStatus;
        controller.timeOff = setInterval(() => {
            // console.log(controller)
            if (controller.isOnLine) { return }       // 在线不操作

            //被踢下线
            if (controller.leaveType == 1) {
                if (controller.userSelect == 1) {
                    this.so = null;
                    this[_login](this.#loginData.userData.username, this.#loginData.userData.password);
                }
                else if (controller.userSelect == 2) { clearInterval(controller.timeOff); sessionStorage.clear(); }
                return
            }
            window.location.reload();
            // 进行登录
            // this[_login](this.#loginData.userData.username, this.#loginData.userData.password);
        }, 5000);
    }
}
